#pragma once

#ifndef _Camera_h_
#define _Camera_h_

#include "CameraType.h"
#include "Frustum.h"
#include "FrustumCullingType.h"
#include "../d3d/d3dUtility.h"

#include <d3dx9.h>

namespace Framework {

class Camera {
public:
    Camera(IDirect3DDevice9* graphicsDevice);
    virtual ~Camera(void);
    Frustum GetFrustum() const;
    void SetFrustum(Frustum val);
    bool GetMirror() const;
    void SetMirror(bool val);
    FLOAT GetMoveSpeed() const;
    void SetMoveSpeed(FLOAT val);
    FLOAT GetYawPitchRollSpeed() const;
    void SetYawPitchRollSpeed(FLOAT val);
    FLOAT GetVisibilityRange() const;
    void SetVisibilityRange(FLOAT val);
    D3DXVECTOR3 GetLookAt() const;
    void SetLookAt(D3DXVECTOR3 lookAt);
    D3DXVECTOR3 GetPosition();
    void SetPosition(D3DXVECTOR3 position);
    void SetProjectionMatrix(D3DXMATRIX projection);
    D3DXVECTOR3 GetUpVector() const;
    void SetUpVector(D3DXVECTOR3 val);
    void BuildViewFrustum();
    D3DXMATRIX GetProjectionMatrix();
    D3DXMATRIX GetViewMatrix();
    FrustumCullingType BoxInFrustum(const d3d::BoundingBox* boundingBox);
    void MoveTo(D3DXVECTOR3 position);
    void Project(D3DXVECTOR3* out, const D3DXVECTOR3* vector, const D3DXMATRIX* world);
    FrustumCullingType SphereInFrustum(const d3d::BoundingSphere* boundingSphere);
    FrustumCullingType SphereInRadius(const d3d::BoundingSphere* boundingSphere, FLOAT radius);
    FrustumCullingType SphereInVisibleRadius(const d3d::BoundingSphere* boundingSphere);
    void Strafe(FLOAT units);
    void Turn(FLOAT angle);
    void Update(FLOAT timeDelta);
    void Walk(FLOAT units);
    void YawPitchRollTo(D3DXVECTOR3 yawPitchRoll);
private:
    Frustum frustum;
    IDirect3DDevice9* graphicsDevice;
    D3DXVECTOR3 lookAt;
    bool mirror;
    FLOAT moveSpeed;
    D3DXVECTOR3 position;
    D3DXMATRIX projection;
    D3DXVECTOR3 rightVector;
    D3DXVECTOR3 targetPosition;
    D3DXVECTOR3 targetYawPitchRoll;
    D3DXVECTOR3 upVector;
    FLOAT visibilityRange;
    D3DVIEWPORT9 viewPort;
    D3DXVECTOR3 yawPitchRoll;
    FLOAT yawPitchRollSpeed;
};

}

#endif